package com.lt.lumentracks.service.Impl;

import com.aliyuncs.exceptions.ClientException;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.lt.lumentracks.entity.po.PostImage;
import com.lt.lumentracks.mapper.PostImageMapper;
import com.lt.lumentracks.service.IPostImageService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.lt.lumentracks.service.ITempFileService;
import com.lt.lumentracks.utils.AliOSSUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * 帖子图片表（外表） 服务实现类
 * </p>
 *
 * @author swl
 * @since 2025-07-28
 */
@Slf4j
@Service
public class PostImageServiceImpl extends ServiceImpl<PostImageMapper, PostImage> implements IPostImageService {

    @Autowired
    private PostImageMapper postImageMapper;
    @Autowired
    private AliOSSUtils aliOSSUtils;
    @Autowired
    private ITempFileService tempFileService;

    /**
     * 更新帖子图片
     * @param postId          帖子id
     * @param newImageUrlList 新的图片url集合
     */
    @Transactional
    @Override
    public void updatePostImage(Integer postId, List<String> newImageUrlList) {
        // 举个例子
        // 数据库查出来的url集合：[a,b,c]
        // 参数中传过来的url集合：[b,a,d]
        // a,b 进行更新操作；
        // c 进行删除操作；
        // d 进行插入操作。

        // 1.获取数据库的图片对象
        List<PostImage> PostImageList_original = this.list(new QueryWrapper<PostImage>()
                .eq("post_id", postId)
                .orderByAsc("sort_order"));

        // 2.对比新旧图片列表，找出需要从云存储删除的图片
        Set<String> oldUrls = PostImageList_original.stream().map(PostImage::getImageUrl).collect(Collectors.toSet());
        Set<String> newUrls = new HashSet<>(newImageUrlList);
        Set<String> urlsToDelete = oldUrls.stream().filter(url -> !newUrls.contains(url)).collect(Collectors.toSet());

        // 3.准备批量更新，插入以及删除的数据
        List<PostImage> imagesToUpdate = new ArrayList<>();
        List<PostImage> imagesToInsert = new ArrayList<>();
        List<Integer> idsToDelete = PostImageList_original.stream()
                .filter(img -> !newUrls.contains(img.getImageUrl())) // 找出需要删除的图片
                .map(PostImage::getId)
                .toList();

        for (int i = 0; i < newImageUrlList.size(); i++) {
            String url = newImageUrlList.get(i);
            Optional<PostImage> existing = PostImageList_original.stream()
                    .filter(img -> img.getImageUrl().equals(url))
                    .findFirst();

            // 该图片的地址在数据库中-->对老图片进行更新操作
            if (existing.isPresent()) {
                PostImage img = existing.get();
                img.setSortOrder(i);
                imagesToUpdate.add(img);
            }
            // 该图片的地址不在数据库中-->对新图片进行插入操作
            else {
                PostImage newImg = new PostImage();
                newImg.setPostId(postId);
                newImg.setImageUrl(url);
                newImg.setSortOrder(i);
                imagesToInsert.add(newImg);
            }
        }

        // 4.执行数据库操作
        if (!imagesToUpdate.isEmpty()) { // 批量更新
            log.info("修改帖子，图片表更新操作，帖子id:{}，更新数量:{}", postId, imagesToUpdate.size());
            this.updateBatchById(imagesToUpdate);
        }
        if (!imagesToInsert.isEmpty()) { // 批量插入
            log.info("修改帖子，图片表插入操作，帖子id:{}，插入数量:{}", postId, imagesToInsert.size());
            this.saveBatch(imagesToInsert);
        }
        if (!idsToDelete.isEmpty()) { // 批量删除
            log.info("修改帖子，图片表删除操作，帖子id:{}，删除数量:{}", postId, idsToDelete.size());
            this.removeByIds(idsToDelete);
        }

        // 5.执行云存储清理（其实前端也可以清理）
        if(!urlsToDelete.isEmpty()) {
            for (String url : urlsToDelete) {
                try {
                    aliOSSUtils.deleteObject(url); // 删除云存储中的图片
                } catch (ClientException e) {
                    throw new RuntimeException(e);
                }
            }
        }

        // 6.把在更新时存入临时文件表里面的图片地址信息删除
        tempFileService.removeBatchByIds(newUrls);
    }


    @Override
    public List<PostImage> findByPostId(Integer postId) {
        QueryWrapper<PostImage> qw = new QueryWrapper<>();
        qw.eq("post_id", postId);
        qw.orderByAsc("sort_order");
        return this.list(qw);
    }


    /** 获取某些帖子的封面图
     * @param postIdList 帖子id集合
     * @return map集合--> key:帖子id  value:对应的封面图url
     */
    @Override
    public Map<Integer, String> FirstImageMap_FindByPostId(List<Integer> postIdList) {
        return postImageMapper.FirstImageMap_FindByPostId(postIdList);
    }
}
